package com.sbillings.messenger.hub.systemtest;

import java.util.Observable;
import java.util.Properties;
import com.sbillings.messenger.hub.MessageGateway;
import com.sbillings.messenger.hub.MessagePublisher;
import com.sbillings.messenger.hub.MessageType;
import com.sbillings.messenger.hub.Publisher;
import com.sbillings.messenger.hub.Subscriber;
import com.sbillings.messenger.hub.EmailNotificationStrategy;
import com.sbillings.messenger.hub.NotificationStrategy;

/**
 * Adjust subscriberName and subscriberEmail, and then run this to test the Messenger hub. 
 * A test message will be emailed to the email address in subscriberEmail.
 * @author steve.billings
 *
 */
public class HubTest {
	private static final String subscriberName = "TBD"; // Set this to your name
	private static final String subscriberEmail = "TBD"; // Set this to your email address
	private static final String messageBody = "This is a test of the Messenger Hub.";
	
	private static final String smtpServerUsername = "TBD";
	private static final String smtpServerPassword = "TBD";

	public static void main(String[] args) {
		hubTest(); 
	}
	
	/** 
	 * Test the Messenger Hub.
	 * Create a MessageGateway to receive messages, and a Publisher to broadcast them.
	 * Then configure a subscriber that wants to receive messages via email.
	 * Finally, invoke the MessageGateway to create and broadcast the message.
	 */
	private static void hubTest() {
		System.out.println("Messenger Hub system test");
		
		// Create the top level objects (MessageGateway, Publisher) and connect them together
		MessagePublisher publisher = new Publisher();
		MessageGateway messageGateway = new MessageGateway(publisher);
		
		// Create the configuration info (SMTP server details) for EmailNotificationStrategy
		Properties emailNotificationStrategyProperties = createEmailNotificationStrategyProperties();

		// Configure a subscriber to receive messages from this source
		String messageSource = "messenger.hub.systemtest.HubTest";
		configureSubscriber(emailNotificationStrategyProperties, publisher, messageSource);
		
		// Do what a servlet would do when it receives a message via http from an application or device:
		// Pass the message ingredients (source, type, body) to the MessageGateway
		// This should result in an email to the subscriber
		messageGateway.processMessage(messageSource, MessageType.INFO.getValue(), messageBody);
	}
	
	/**
	 * Configure a subscriber that is interested in receiving messages from this test class, that wants to receive messages via email.
	 * @param emailNotificationStrategyProperties Config info for the EmailNotificationStrategy object (SMTP server details)
	 * @param publisher The publisher that will broadcast messages
	 * @param sourceToSubscribeTo The source this subscriber is interested in (= this class)
	 */
	private static void configureSubscriber(Properties emailNotificationStrategyProperties, MessagePublisher publisher, String sourceToSubscribeTo) {
		// Create a subscriber/observer to receive messages
		Subscriber subscriber = new Subscriber(subscriberName);
		subscriber.setEmail(subscriberEmail);
		
		subscriber.addMessageSource(sourceToSubscribeTo); // subscribe only to this message source
		NotificationStrategy notificationStrategy = new EmailNotificationStrategy(emailNotificationStrategyProperties);
		subscriber.addNotificationStrategy(notificationStrategy); // notification strategy = Email
		
		// Register that subscriber/observer to receive messages
		Observable observable = (Observable)publisher; // Since this test will act as the admin interface......... TBD
		observable.addObserver(subscriber); // Normally done through the (future) admin interface, which will use Type Observer
	}
	
	/**
	 * Set up the configuration for the EmailNotificationStrategy
	 * @return a Properties object with the configuration for EmailNotificationStrategy
	 */
	private static Properties createEmailNotificationStrategyProperties() {
		Properties properties = new Properties();
		properties.put("username", smtpServerUsername);
		properties.put("password", smtpServerPassword);
		properties.put("mail.smtp.auth", "true");
		properties.put("mail.smtp.starttls.enable", "true");
		properties.put("mail.smtp.host", "smtp.gmail.com");
		properties.put("mail.smtp.port", "587");
		return properties;
	}

}
